package com.example.mgs.Service.Impl;

import com.example.common.constants.OtherConstants;
import com.example.common.constants.RdsConstants;
import com.example.common.constants.RoleConstants;
import com.example.common.domain.Messages.UserActivityMessage;
import com.example.mgs.Service.ActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Map;

@Service
public class ActivityServiceImpl implements ActivityService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void processActivity(UserActivityMessage message, String userType) {
        String userId = message.getUserId();
        String path = message.getPath();
        String today = LocalDate.now().toString();

        // 1. 统计用户今日访问次数
        redisTemplate.opsForValue().increment(userType + RdsConstants.USER_ACTIVITY + userId + ":" + today);

        // 2. 统计用户模块访问（根据路径确定模块）
        String module = getModuleByPath(path, userType);
        if (module != null) {
            redisTemplate.opsForHash().increment(
                    userType + RdsConstants.USER_MODULE + userId + ":" + today,
                    module,
                    1
            );
        }   //老师或者学生，模块，id，时间

        // 3. 记录最后访问时间
        redisTemplate.opsForValue().set(userType + RdsConstants.USER_LAST_VISIT + userId, message.getTimestamp());
        // 4. 统计总活跃用户数（使用HyperLogLog去重）
        redisTemplate.opsForHyperLogLog().add(userType + RdsConstants.USER_ACTIVE + today, userId);

        long timestamp = message.getTimestamp();
        LocalDate date = Instant.ofEpochMilli(timestamp)
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        int weekNumber = getWeekNumber(date); // 计算周次
        // 1. 存储周活跃用户（HyperLogLog）
//        String weeklyActiveKey = String.format("%s:active:week:%d", userType, weekNumber);
        String weeklyActiveKey = String.format(RdsConstants.WEEKLY_ACTIVE_KEY, userType, weekNumber);
        redisTemplate.opsForHyperLogLog().add(weeklyActiveKey, userId);
        // 2. 存储周模块访问（Hash）
//        String weeklyModuleKey = String.format("%s:module:week:%d:%s", userType, weekNumber, userId);
        String weeklyModuleKey = String.format(RdsConstants.USER_MODULE_KEY, userType, weekNumber, userId);
        if (module != null) {
            redisTemplate.opsForHash().increment(weeklyModuleKey, module, 1);
        }
    }


    public String getModuleByPath(String path, String userType) {
        if (path == null || userType == null) {
            return "其他模块";
        }
        Map<String, String> moduleMap = null;
        if (RoleConstants.TEACHER.equals(userType)) {              //老师方面
            moduleMap = RoleConstants.TEACHER_MODULE_MAP;
        } else if (RoleConstants.STUDENT.equals(userType)) {       //  //老师方面
            moduleMap = RoleConstants.STUDENT_MODULE_MAP;
        }
        if (moduleMap != null) {
            String moduleName = RoleConstants.getModuleName(moduleMap, path);
            if (moduleName != null) {
                return moduleName;
            }
        }
        return "其他模块";
    }

    /**
     * 根据目标日期计算周次（以2025-05-20为第一周）
     *
     * @param targetDate 目标日期
     * @return 周次（从1开始）
     */

    public int getWeekNumber(LocalDate targetDate) {
        LocalDate baseDate = LocalDate.of(OtherConstants.ACTIVE_YEAR,
                OtherConstants.ACTIVE_MONTH, OtherConstants.ACTIVE_DAY); // 第一周起始日（周一）
        long daysDiff = ChronoUnit.DAYS.between(baseDate, targetDate);
        return (int) (daysDiff / 7) + 1; // 向上取整，确保7天为一周
    }
}
